import React, { useState } from 'react';
import { Box, ListBase, makeToast } from '@nova-hf/ui';
import { ErrorBanner as NotificationBannerWithLoading } from 'beta/components/error/ErrorBanner';
import UI from 'beta/store/ui';
import { betaRoutingMaster, formatDate } from 'beta/utils/helpers';
import { useTranslation } from 'beta/utils/i18n';
import { inject, observer } from 'mobx-react';
import { useRouter } from 'next/router';
import {
  ContractStatus,
  PayerChangeRequestStatus,
  useCancelPayerChangeRequestMutation,
  useContractStatusQuery,
  useCustomerNameLazyQuery,
  usePayerChangeRequestLazyQuery,
  useProcessPayerChangeRequestMutation,
} from 'typings/graphql';

type PendingPayerChangesProps = {
  ui?: UI;
  isInSettings?: boolean;
};
const PendingPayerChanges = ({ ui, isInSettings }: PendingPayerChangesProps) => {
  const { t } = useTranslation('fiber');

  const router = useRouter();
  const [contractId, setContractId] = useState('');
  const [customerName, setCustomerName] = useState('');
  const [formattedDate, setFormattedDate] = useState('');
  const [payerChangeId, setPayerChangeId] = useState('');
  const customerId = router.query.customerId;
  const serviceId = router.query.serviceId;

  const { loading: loadingContracts, error: contractsError } = useContractStatusQuery({
    variables: {
      input: {
        serviceId: serviceId?.toString(),
        customerId: customerId?.toString(),
      },
    },
    onCompleted(data) {
      if (data?.contracts?.contracts?.length) {
        const pendingOrActiveContract = data.contracts.contracts.find(
          (contract) =>
            contract.status === ContractStatus.Active || contract.status === ContractStatus.Pending,
        );
        if (pendingOrActiveContract?.id) {
          setContractId(pendingOrActiveContract.id);
          getPayerChanges({
            variables: {
              input: {
                origin_payer_id: customerId?.toString() ?? '',
                origin_contractId: pendingOrActiveContract?.id,
              },
            },
          });
          getNewPayerChanges({
            variables: {
              input: {
                new_payer_id: customerId?.toString() ?? '',
                new_contract_id: pendingOrActiveContract?.id,
              },
            },
          });
        }
      }
    },
    fetchPolicy: 'cache-and-network',
    skip: !serviceId || !customerId,
  });

  const [cancelPayerChange, { loading: loadingCancelPayerChange }] =
    useCancelPayerChangeRequestMutation({
      variables: {
        input: {
          id: payerChangeId,
        },
      },
      onCompleted(data) {
        if (data?.cancelPayerChangeRequest?.id) {
          makeToast.success(
            t('pendingPayerChanges.toast.successTitle'),
            t('pendingPayerChanges.toast.successDescriptionCancel', { customerName }),
          );
          handleRedirectAfterCancel();
        }
      },
      onError(error) {
        if (error instanceof Error) {
          makeToast.danger(t('pendingPayerChanges.toast.errorTitle'), error.message);
        }
      },
    });

  const [processPayerChange, { loading: loadingProcessPayerChange }] =
    useProcessPayerChangeRequestMutation({
      variables: {
        input: {
          id: payerChangeId,
        },
      },
      onCompleted(data) {
        if (data?.processPayerChangeRequest?.id) {
          makeToast.success(
            t('pendingPayerChanges.toast.successTitle'),
            t('pendingPayerChanges.toast.successDescriptionProcess', { customerName }),
          );
          setPayerChangeId('');
        }
      },
      onError(error) {
        if (error instanceof Error) {
          makeToast.danger(t('pendingPayerChanges.toast.errorTitle'), error.message);
        }
      },
    });

  const [getPayerChanges, { loading: loadingAsOriginalPayer }] = usePayerChangeRequestLazyQuery({
    onCompleted(data) {
      const originalPayerChange = data?.payerChangeRequest?.find(
        (request) => request?.originContractId === contractId,
      );
      if (originalPayerChange && originalPayerChange.status === PayerChangeRequestStatus.Pending) {
        setPayerChangeId(originalPayerChange.id);
        setFormattedDate(formatDate(originalPayerChange.effectiveDate ?? '', 'd. MMMM yyyy'));
        getCustomerName({
          variables: {
            input: {
              id: originalPayerChange?.newContractPayerId,
            },
          },
        });
      }
    },
    fetchPolicy: 'cache-and-network',
  });

  const [getNewPayerChanges, { loading: loadingAsNewPayer }] = usePayerChangeRequestLazyQuery({
    onCompleted(data) {
      const newPayerChange = data?.payerChangeRequest?.find(
        (request) => request?.newContractId === contractId,
      );
      if (newPayerChange && newPayerChange.status === PayerChangeRequestStatus.Pending) {
        setPayerChangeId(newPayerChange.id);
        setFormattedDate(formatDate(newPayerChange?.effectiveDate ?? '', 'd. MMMM yyyy'));
        setCustomerName('þú');
      }
    },
    fetchPolicy: 'cache-and-network',
  });

  const [getCustomerName, { loading: loadingCustomerName }] = useCustomerNameLazyQuery({
    onCompleted(data) {
      if (data?.customer?.name) setCustomerName(data.customer.name);
    },
  });

  const [getCustomerNationalId, { loading: loadingCustomerNationalId }] = useCustomerNameLazyQuery({
    onCompleted(data) {
      if (data?.customer?.nationalId) {
        betaRoutingMaster(
          `/beta/${customerId}/thjonustur`,
          router,
          data?.customer?.nationalId,
          '/beta/:customerId/thjonustur',
        );
      }
    },
  });

  const handleRedirectAfterCancel = () => {
    getCustomerNationalId({
      variables: {
        input: {
          id: customerId?.toString() ?? '',
        },
      },
    });
  };

  const isLoadingData =
    loadingAsOriginalPayer ||
    loadingAsNewPayer ||
    loadingContracts ||
    loadingCustomerName ||
    loadingCustomerNationalId;

  if (contractsError || !payerChangeId || isLoadingData) return null;

  return (
    <Box marginBottom={5}>
      <NotificationBannerWithLoading
        hasPingAlert={!isInSettings}
        eyebrowTexts={[t('pendingPayerChanges.eyebrowText')]}
        titles={[t('pendingPayerChanges.title')]}
        descriptions={
          formattedDate && customerName
            ? [
                t('pendingPayerChanges.description', {
                  formattedDate,
                  customerName,
                }),
              ]
            : [t('pendingPayerChanges.descriptionFallback')]
        }
        icon="transfer"
        color={ui?.serviceColor ?? 'pink'}
        showLoading={isLoadingData}
        refetchButton={{
          text: t('pendingPayerChanges.buttons.activate'),
          icon: 'longArrowRight',
          isDisabled: loadingCancelPayerChange,
          isLoading: loadingProcessPayerChange,
          onClick: () => processPayerChange(),
        }}
        contactButton={{
          text: t('pendingPayerChanges.buttons.cancel'),
          isLoading: loadingCancelPayerChange,
          isDisabled: loadingProcessPayerChange,
          onClick: () => cancelPayerChange(),
        }}
        loadingComponent={
          <>
            <ListBase isLoading height={30} />
          </>
        }
      />
    </Box>
  );
};

export default inject('ui', 'authentication')(observer(PendingPayerChanges));
